#ifndef TESTCASE_H
#define TESTCASE_H
#include "QuickLib.h"

#include <QtDebug>
#include <QSharedData>
#include <QString>
#include <QTime>
#include <QVariant>

#include <type/CProperty.h>

#define TESTCASE_PROPS(TND) \
    TND(QTime, Time, QTime()) \
    TND(int, Level, 0) \
    TND(int, Relation, 0) \
    TND(QString, ExpectedName, QString()) \
    TND(QVariant, ExpectedValue, QString()) \
    TND(QString, ActualName, QString()) \
    TND(QVariant, ActualValue, QString()) \
    TND(QString, Message, QString()) \
    TND(int, SourceLine, 0) \
    TND(QString, FunctionInfo, QString()) \
    TND(QString, FunctionFile, QString()) \
    TND(int, FunctionLine, 0) \

class QUICKSHARED_EXPORT QutCase
{
public:
    enum Level
    {
        nullLevel=0,
        Summary,
        TestRun,
        Library,
        Progress,
        Leave,
        Enter,
        Pass,
        Info,
        ToDo,
        Mismatch,
        Error,
        Expect,
        MustDo,
        Assert,
        Quit,
        Shutdown,
        sizeLevel
    };

    enum Relation
    {
        nullRelation=0,
        Data,
        Equal,
        NotEqual,
        LessThan,
        LessEqual,
        MoreThan,
        MoreEqual,
        False,
        True,
        sizeRelation,
        Not=0x8000000,
    };

    typedef QList<QutCase> List;

    DECLARE_PROPERTIES(TESTCASE_PROPS)

public:
    QutCase(void);
    QutCase(const bool);
    QutCase(const Level level,
              const Relation relation,
              const QString & expectedName,
              const QVariant & expectedValue,
              const QString & actualName,
              const QVariant & acutalValue,
              const int sourceLine,
              const QString & message=QString());
    Level evaluate(void) const;
    QString toString(const int flags=0) const;
    void debug(void) const;

private:
    QString prefixString(const Level level) const;
    QString bodyString(const Level level,
                       const Relation rel) const;
    QString compareBody(const Level level,
                        const Relation rel) const;
    QString levelSuccess(const Level level) const;
    QString relationString(const Relation rel) const;
    static QStringList smRelationString_qsl;
    //static int metaType_i;
};
Q_DECLARE_METATYPE(QutCase)

#define TESTEVENT(sev, rel, exp, act) QutCase(sev, rel, #exp, exp, #act, act, __LINE__)

#endif // TESTCASE_H
